package com.cmwa.scbp.business.myHome.todo.controller;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.cmwa.scbp.base.mvc.controller.BaseController;
import com.cmwa.scbp.base.mvc.entity.Page;
import com.cmwa.scbp.base.mvc.entity.Result;
import com.cmwa.scbp.base.mvc.entity.SearchParam;
import com.cmwa.scbp.business.myHome.todo.entity.OverviewData;
import com.cmwa.scbp.business.myHome.todo.entity.TodoBizRelVo;
import com.cmwa.scbp.business.myHome.todo.entity.TodoVo;
import com.cmwa.scbp.business.myHome.todo.enums.ServiceType;
import com.cmwa.scbp.business.myHome.todo.enums.TodoBizType;
import com.cmwa.scbp.business.myHome.todo.service.TodoService;
import com.cmwa.scbp.sys.attach.entity.AttachRelExtVo;
import com.cmwa.scbp.sys.attach.entity.AttachVo;
import com.cmwa.scbp.sys.attach.service.AttachService;
import com.cmwa.scbp.sys.dictionary.entity.DictionaryVo;
import com.cmwa.scbp.sys.msg.util.StringUtil;
import com.cmwa.scbp.sys.opinion.entity.HistoryOpinionVo;
import com.cmwa.scbp.sys.opinion.enums.HisType;
import com.cmwa.scbp.sys.opinion.service.HistoryOpinionService;
import com.cmwa.scbp.utils.DateUtils;
import com.cmwa.scbp.utils.JsonUtil;
import com.cmwa.scbp.utils.SessionUtils;
import com.cmwa.scbp.utils.cached.DictionaryCached;
import com.google.common.base.Joiner;

import net.sf.json.JSONArray;

/**
 * 标准理财产品模板控制器
 * 
 * @author ex-zuotc
 * @date 2019-01-23 13:21:17
 */
@Controller
@RequestMapping("/business/myHome/todoAndOutput")
public class TodoAndOutputController extends BaseController {
	
	private static final Log logger = LogFactory.getLog(TodoAndOutputController.class);

	private final static String JSP_PATH = "business/myHome/todoAndOutput/";
	@Resource
	private TodoService todoService;
	@Resource
	private AttachService attachService;
	@Resource
	private HistoryOpinionService historyOpinionService;
//	@Resource
//	private NavInfoService navInfoService;
	
	@RequestMapping("/overview")
	public String overview(ModelMap model) {
		return JSP_PATH + "overview";
	}
	
	@RequestMapping("/todoListPage")
	@ResponseBody
	public Page<TodoVo> todoListPage(SearchParam param) {
		Page<TodoVo> list = todoService.todoListPage(param);
		return list;
	}
	
	@RequestMapping("/listAllTodo")
	@ResponseBody
	public List<TodoVo> listAllTodo() {
		List<TodoVo> list = todoService.listAllTodo();
		return list;
	}
	
	/**
	 * @return
	 */
	@RequestMapping("/getOverviewData")
	@ResponseBody
	public Result<List<OverviewData>> getOverviewData() {
		Result<List<OverviewData>> result = new Result<>();
		result.setSuccess(true);
		try {
			List<OverviewData> overviewData = todoService.getOverviewData();
			result.setObject(overviewData);
		} catch (Exception e) {
			result.setSuccess(false);
			result.setMessage("query exception" + e.getMessage());
		}
		return result;
	}
	
	/**
	 * 产出下载页面
	 * @author ex-hejm
	 * @date 2019年2月14日下午5:21:51
	 * @param model
	 * @return
	 */
	@RequestMapping("/outDownloadView")
	public String outDownloadView(Model model, @RequestParam("serviceType") String serviceType) {
		
		String currentUserId = SessionUtils.getEmployee().getID();
		String today = DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_yMd_EN2);
		TodoVo todoVo = new TodoVo();
		todoVo.setServiceType(serviceType);
		todoVo.setEndTime(today);
		todoVo.setStatus("E");
		todoVo.setEmpId(currentUserId);
		
		List<TodoVo> complateTodos = todoService.queryList(todoVo);
		
		model.addAttribute("complateTodos", complateTodos);
		model.addAttribute("serviceType", serviceType);
		
		return JSP_PATH + "outDownloadView";
	}
	
	@RequestMapping("/addView")
	public String addView(Model model) {
		model.addAttribute("operType", "add");
		
		//加载拓展字段下拉选项
		List<DictionaryVo> dictionaryList = DictionaryCached.getDictionaryByRootType("TODO_FILE_TYPE");
		//如果拓展字段下拉选项信息不为空，则将拓展字段下拉选项信息转成JSON格式
		String fileType2Json = "";
		if(null != dictionaryList){
			fileType2Json = StringUtil.changeSpecialCharacter(JSONArray.fromObject(dictionaryList).toString());
		}
		

		List<DictionaryVo> todoTyps = DictionaryCached.getDictionaryByRootType("TODO_TYPE");
		
		model.addAttribute("fileType2Json", fileType2Json);
		model.addAttribute("todoTyps", JsonUtil.toJson(todoTyps));
		
		return JSP_PATH + "todoAdd";
	}

	@RequestMapping("/todoFileUploadView")
	public String fileUploadView(@RequestParam("id")String id, Model model) {
		TodoVo todo = todoService.getTodoById(id);
		
		todoService.checkTodoStatus(id, "fileUpload");
		
		List<AttachVo> attachs = attachService.queryAttachByRelIdAndType(todo.getId(), "MY_TODO");
		if(CollectionUtils.isNotEmpty(attachs)){
			for (AttachVo attachVo : attachs) {
				List<AttachRelExtVo> list = attachService.listAttachExtByAttId(attachVo.getAttId());
				attachVo.setExtList(list);
			}
		}
		model.addAttribute("attachs", attachs);
		

		model.addAttribute("todo", todo);
		model.addAttribute("operType", "fileUpload");
		
		//加载拓展字段下拉选项
		List<DictionaryVo> dictionaryList = DictionaryCached.getDictionaryByRootType("TODO_FILE_TYPE");
		//如果拓展字段下拉选项信息不为空，则将拓展字段下拉选项信息转成JSON格式
		String fileType2Json = "";
		if(null != dictionaryList){
			fileType2Json = StringUtil.changeSpecialCharacter(JSONArray.fromObject(dictionaryList).toString());
		}
		model.addAttribute("fileType2Json", fileType2Json);
		
		// 显示历史意见
		addHistoryOpinions(id, model);
		
		return JSP_PATH + "todoFileUploadOrConfirm";
	}
	
	
	@RequestMapping("/fileEndView")
	public String fileEndView(@RequestParam("id")String id, @RequestParam(value = "bizType", required = false)String bizType, Model model) {
		TodoVo todo = todoService.getTodoById(id);
		
		todoService.checkTodoStatus(id, "fileEnd");
		
		List<AttachVo> attachs = attachService.queryAttachByRelIdAndType(todo.getId(), "MY_TODO");
		if(CollectionUtils.isNotEmpty(attachs)){
			for (AttachVo attachVo : attachs) {
				List<AttachRelExtVo> list = attachService.listAttachExtByAttId(attachVo.getAttId());
				attachVo.setExtList(list);
			}
		}
		model.addAttribute("attachs", attachs);

		// 报告
		List<AttachVo> fileEndAttachs = attachService.queryAttachByRelIdAndType(todo.getId(), "MY_TODO_FILE_END");
		String fileEndAttachList = null;
		if(CollectionUtils.isNotEmpty(fileEndAttachs)){
			fileEndAttachList  = StringUtil.changeSpecialCharacter(JSONArray.fromObject(fileEndAttachs).toString());
		}
		
		model.addAttribute("todo", todo);
		model.addAttribute("attachPermission", "fileEnd");
		
		model.addAttribute("fileEndAttachList", fileEndAttachList);
		model.addAttribute("operType", "fileEnd");
		
		// 用作附件上传来源
		if (StringUtils.isEmpty(bizType)) {
			bizType = "MY_TODO_FILE_END";
		}
		model.addAttribute("bizType", bizType);
		
		// 显示历史意见
		addHistoryOpinions(id, model);
		
		return JSP_PATH + "todoFileUploadOrConfirm";
	}
	
	@RequestMapping("/fileDetailView")
	public String fileDetailView(@RequestParam("id")String id, Model model) {
		TodoVo todo = todoService.getTodoById(id);
		List<AttachVo> attachs = attachService.queryAttachByRelIdAndType(todo.getId(), "MY_TODO");
		if(CollectionUtils.isNotEmpty(attachs)){
			for (AttachVo attachVo : attachs) {
				List<AttachRelExtVo> list = attachService.listAttachExtByAttId(attachVo.getAttId());
				attachVo.setExtList(list);
			}
		}
		model.addAttribute("attachs", attachs);

		// 报告
		List<AttachVo> fileEndAttachs = null;
		String fileEndAttachList = null;
		String empType = SessionUtils.getEmployee().getEmpType();
		// 只有当状态为已完成时，或为内部用户（不管状态）时，才需查询产出文件
		if (StringUtils.equals(todo.getStatus(), "E") || StringUtils.equals(empType, "IN")) {
			fileEndAttachs = attachService.queryAttachByRelIdAndType(todo.getId(), "MY_TODO_FILE_END");
			if (CollectionUtils.isNotEmpty(fileEndAttachs)) {
				fileEndAttachList  = StringUtil.changeSpecialCharacter(JSONArray.fromObject(fileEndAttachs).toString());
			}
		}
		
		model.addAttribute("attachPermission", false);
		model.addAttribute("todo", todo);
		
		model.addAttribute("fileEndAttachList", fileEndAttachList);
		model.addAttribute("operType", "fileDetail");
		
		// 显示历史意见
		addHistoryOpinions(id, model);
		
		return JSP_PATH + "todoFileUploadOrConfirm";
	}
	
	private void addHistoryOpinions(String id, Model model) {
		HistoryOpinionVo historyOpinionVo = new HistoryOpinionVo();
		historyOpinionVo.setSourceId(id);
		historyOpinionVo.setHisType(HisType.MY_TODO);
		List<HistoryOpinionVo> historyOpinions = historyOpinionService.queryHistoryOpinionInfoById(historyOpinionVo);
		model.addAttribute("historyOpinions", historyOpinions);
	}
	
	@RequestMapping("/save")
	public String save(
			TodoVo todoVo, 
			@RequestParam(value = "attIds", required = false)String attIds, 
			@RequestParam(value = "fileEndAttId", required = false)String fileEndAttId, 
			@RequestParam(value = "attachJson", required = false)String attachJson, 
			@RequestParam("operType")String operType, 
			@RequestParam(value="opinion", required=false)String opinion, 
			@RequestParam(value = "confirmResult", required = false)String confirmResult) {
		todoService.save(todoVo, attIds, fileEndAttId, attachJson, operType, confirmResult, opinion);
		return redirectSuccess();
	}
	
	@RequestMapping("/todoFileConfirmView")
	public String todoFileConfirmView(@RequestParam("id")String id, Model model) {
		TodoVo todo = todoService.getTodoById(id);
		
		todoService.checkTodoStatus(id, "fileConfirm");
		
		List<AttachVo> attachs = attachService.queryAttachByRelIdAndType(todo.getId(), "MY_TODO");
		if(CollectionUtils.isNotEmpty(attachs)){
			for (AttachVo attachVo : attachs) {
				List<AttachRelExtVo> list = attachService.listAttachExtByAttId(attachVo.getAttId());
				attachVo.setExtList(list);
			}
		}
		model.addAttribute("attachs", attachs);
		
		//加载拓展字段下拉选项
		List<DictionaryVo> dictionaryList = DictionaryCached.getDictionaryByRootType("TODO_FILE_TYPE");
		//如果拓展字段下拉选项信息不为空，则将拓展字段下拉选项信息转成JSON格式
		String fileType2Json = "";
		if(null != dictionaryList){
			fileType2Json = StringUtil.changeSpecialCharacter(JSONArray.fromObject(dictionaryList).toString());
		}
		model.addAttribute("fileType2Json", fileType2Json);
		
		model.addAttribute("todo", todo);
		model.addAttribute("operType", "fileConfirm");
		
		// 显示历史意见
		addHistoryOpinions(id, model);
		
		return JSP_PATH + "todoFileUploadOrConfirm";
	}
	
	@RequestMapping("/toUploadListView")
	public String toUploadListView(
			@RequestParam("serviceType")String serviceType, 
			Model model) {
		model.addAttribute("serviceType", serviceType);
		return JSP_PATH + "toUploadList";
	}
	
	/**
	 * 材料上传页的列表
	 * @param param
	 * @return
	 */
	@RequestMapping("/toUploadListPage")
	@ResponseBody
	public Page<TodoVo> toUploadListPage(SearchParam param) {
		Page<TodoVo> list = todoService.toUploadListPage(param);
		return list;
	}
	
	/**
	 * 无材料上传
	 * @param id
	 * @return
	 */
	@RequestMapping("/noFileUpload")
	@ResponseBody
	public Result<Object> noFileUpload(@RequestParam("id")String id) {
		Result<Object> result = new Result<>();
		result.setSuccess(true);
		result.setMessage("操作成功");
		try {
			todoService.noFileUpload(id);
		} catch (Exception e) {
			result.setSuccess(false);
			result.setMessage("query exception" + e.getMessage());
		}
		return result;
	}
	
	@RequestMapping("/queryTodoCount")
	@ResponseBody
	public Result<Integer> queryTodoCount() {
		Result<Integer> result = new Result<>();
		result.setSuccess(true);
		result.setMessage("操作成功");
		try {
			int todoCount = todoService.queryTodoCount();
			result.setObject(todoCount);
		} catch (Exception e) {
			result.setSuccess(false);
			result.setMessage("query exception" + e.getMessage());
		}
		return result;
	}
	
	/**
	 * 供业务模块跳转的产出上传页面
	 * @param bizType
	 * @param bizId
	 * @param request
	 * @return
	 */
	@RequestMapping("/toEndFileUploadView4Biz")
	public String toEndFileUploadView4Biz(@RequestParam("bizType")String bizType, @RequestParam("bizId")String bizId, HttpServletRequest request) {
		List<TodoBizRelVo> relVos = todoService.queryRelVoByBiz(bizType, bizId);
		if (CollectionUtils.isNotEmpty(relVos)) {
			return "redirect:/business/myHome/todoAndOutput/fileEndView.do?bizType=" + bizType + "&id=" + relVos.get(0).getTodoId();
		} else {
			return redirectExecFaild();
		}
	}
	
	/**
	 * 供业务模块材料下载（批量）
	 * @return
	 */
	@RequestMapping("/batchTodoFileDownload4Biz")
	public String batchTodoFileDownload4Biz(@RequestParam("bizType")String bizType, @RequestParam("bizId")String bizId,
			HttpServletResponse response, HttpServletRequest request, Model model) {
		List<TodoBizRelVo> relVos = todoService.queryRelVoByBiz(bizType, bizId);
		if (CollectionUtils.isNotEmpty(relVos)) {
			List<String> idList = new ArrayList<>();
			for (TodoBizRelVo relVo : relVos) {
				idList.add(relVo.getTodoId());
			}
			String ids = Joiner.on(",").join(idList);
			String serviceType = relVos.get(0).getTodoServiceType();
			
			this.downloadInputFiles(ids, serviceType, bizType, response, request);
			
			return null;
		} else {
			model.addAttribute("exception", "未找到对应数据或无附件可下载");
			return redirectExecFaild();
		}
	}
	

	/**
	 * 供业务模块产出下载（批量）
	 * @return
	 */
	@RequestMapping("/batchEndFileDownload4Biz")
	public String batchEndFileDownload4Biz(@RequestParam("bizType")String bizType, @RequestParam("bizId")String bizId, Model model,
			HttpServletResponse response, HttpServletRequest request) {
		List<TodoBizRelVo> relVos = todoService.queryRelVoByBiz(bizType, bizId);
		if (CollectionUtils.isNotEmpty(relVos)) {
			List<String> idList = new ArrayList<>();
			for (TodoBizRelVo relVo : relVos) {
				idList.add(relVo.getTodoId());
			}
			String ids = Joiner.on(",").join(idList);
			String serviceType = relVos.get(0).getTodoServiceType();
			this.downloadOutputFiles(ids, serviceType, bizType, response, request);
			
			return null;
		} else {
			model.addAttribute("exception", "未找到对应的待办数据");
			return redirectExecFaild();
		}
	}
	
	/**
	 * 供业务模块校验是否有材料或产出
	 * @param bizType
	 * @param bizId
	 * @param fileType
	 * @return
	 */
	@RequestMapping("/validateExistsFile")
	@ResponseBody
	public Result<Object> validateExistsFile(@RequestParam("bizType")String bizType, @RequestParam("bizId")String bizId, @RequestParam("fileType")String fileType) {
		return todoService.validateExistsFile(bizType, bizId, fileType);
	}
	
	/**
	 * 打包下载材料附件
	 * @param ids
	 * @param serviceType
	 * @param bizType 
	 * @param response
	 * @param request
	 */
	private void downloadInputFiles(String ids, String serviceType, String bizType, HttpServletResponse response, HttpServletRequest request) {
		List<TodoVo> todoVos = todoService.queryTodoInputFiles(ids);
		if (CollectionUtils.isNotEmpty(todoVos)) {
			String fileName = TodoBizType.valueOf(bizType).getText() + "-材料";
			Map<String, String> downloadMap = new HashMap<>();
			for (TodoVo todoVo : todoVos) {
				String todoDate = DateUtils.formatDate(todoVo.getTodoDate(), DateUtils.DATE_FORMAT_yMd_EN);
				String key = todoVo.getTodoTypeName() + todoDate;
				downloadMap.put(key, todoVo.getAttId());
			}
			attachService.downloadAttachZip(downloadMap, fileName, request, response);
		} else {
			attachService.downloadAttachZip("", ServiceType.valueOf(serviceType).getText(), request, response);
		}
	}
	
	/**
	 * 打包下载产出附件
	 * @param ids
	 * @param serviceType
	 * @param bizType 
	 * @param response
	 * @param request
	 */
	private void downloadOutputFiles(String ids, String serviceType, String bizType, HttpServletResponse response, HttpServletRequest request) {
		List<TodoVo> todoVos = todoService.queryTodoOutFiles(ids);
		if (CollectionUtils.isNotEmpty(todoVos)) {
			String serviceTypeName = todoVos.get(0).getServiceTypeName();
			String fileName = serviceTypeName + "-产出";
			if (StringUtils.isNotEmpty(bizType)) {
				fileName = TodoBizType.valueOf(bizType).getText() + "-产出";
			}
			
			Map<Date, List<String>> navFileMap = new HashMap<>();
			
			Map<String, String> downloadMap = new HashMap<>();
			for (TodoVo todoVo : todoVos) {
				String todoDate = DateUtils.formatDate(todoVo.getTodoDate(), DateUtils.DATE_FORMAT_yMd_EN);
				String key = todoVo.getTodoTypeName() + todoDate;
				downloadMap.put(key, todoVo.getAttId());
				
				// 业务类型为空，为“我的”页面批量下载产出
				// 如果有“估值”类型的产出，需同步下载接口文件
				// 每天一个接口文件，按待办日期分组系列产品编号
				if (StringUtils.isEmpty(bizType)  && StringUtils.equals(serviceType, "CUST_EQUITY") && StringUtils.equals(todoVo.getTodoType(), "ESTIMATE")) {
					Date navkey = todoVo.getTodoDate();
					if (!navFileMap.containsKey(navkey)) {
						navFileMap.put(navkey, new ArrayList<String>());
					}
					
					navFileMap.get(navkey).add(todoVo.getPrjCode());
				}
			}
			
			Map<String, Map<String, File>> zipFileMap = null;
			if (!navFileMap.isEmpty()) {
				zipFileMap = new HashMap<String, Map<String, File>>();
				
				for (Date date : navFileMap.keySet()) {
					String theDate = DateUtils.formatDate(date, DateUtils.DATE_FORMAT_yMd_EN);
//					String prjCodes = Joiner.on(",").join(navFileMap.get(date));
//					File navFile = navInfoService.createNavFile(theDate, null, prjCodes);
					File navFile = new File("");
					
					String bizDate = DateUtils.formatDate(DateUtils.parseDate(theDate, DateUtils.DATE_FORMAT_yMd_EN), DateUtils.DATE_FORMAT_yMd_EN2);
					String navFileName = "AP_NAV_" + bizDate + "_01";
					String dir = "净值接口文件" + theDate;
					
					// 将净值接口文件传入压缩包逻辑中进行打包
					Map<String, File> map = zipFileMap.get(dir);
					if (map == null || map.isEmpty()) {
						map = new HashMap<String, File>();
						zipFileMap.put(dir, map);
					}
					map.put(navFileName, navFile);
				}
			}
			
			attachService.downloadAttachZip(downloadMap, zipFileMap, fileName, request, response);
		} else {
			attachService.downloadAttachZip("", ServiceType.valueOf(serviceType).getText(), request, response);
		}
	}
	

	/**
	 * “我的”下载产出（打包下载附件）
	 * @param id
	 * @throws IOException 
	 */
	@RequestMapping("/downloadOutput")
	public String downloadOutput(
			@RequestParam("ids")String ids, 
			@RequestParam("serviceType")String serviceType, 
			HttpServletResponse response, HttpServletRequest request,
			Model model) throws IOException {
		
		// 查出待办信息及产出信息
		// 产品名称，待办类型，附件ID，文件名
		try {
			this.downloadOutputFiles(ids, serviceType, null, response, request);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		model.addAttribute("exception", "未找到对应数据或无附件可下载");
		return redirectExecFaild();
	}
	
	/**
	 * 删除待办
	 * @param id
	 * @return
	 */
	@RequestMapping("/deleteTodo")
	@ResponseBody
	public Result<Object> deleteTodo(@RequestParam("id")String id) {
		Result<Object> result = new Result<>();
		result.setSuccess(true);
		result.setMessage("操作成功");
		try {
			todoService.deleteTodo(id);
		} catch (Exception e) {
			logger.error("待办删除失败，id=" + id, e);
			result.setSuccess(false);
			result.setMessage("删除失败");
		}
		return result;
	}
}
